<?php
/**
* @software         [JiJinCMS]
* @author           [上海集锦信息科技有限公司]
* @website          [http://www.jijinweb.com]
* @email            [sunny@jijinweb.com]
**/
namespace app\admin\controller;
use think\facade\View;
use think\facade\Db;
use think\facade\Request;
class Cat extends \app\admin\controller\Admin{
    private $modelid,$select_catid;
    public function __construct(\think\App $app) {
        parent::__construct($app);
        $modelList=Db::name("model")->where("status",1)->order("sort asc,modelid desc")->select()->toArray();
        View::assign("modeList",$modelList);
        $this->model=new \app\admin\model\CatModel();
        $this->ModelModel=new \app\admin\model\ModelModel();
        $this->RouteModel=new \app\admin\model\RouteModel();
        $this->CatFieldModel=new \app\admin\model\CatFieldModel();
        $this->validate=new \app\admin\validate\CatValidate();
        //排序选项
        $this->orderInc=array(
            "sort asc,is_top desc,is_good desc,newstime desc,id desc"=>"默认排序",
            "newstime desc"=>"按发布时间降序排序",
            "id desc"=>"按ID降序排序",
            "views desc"=>"按点击率降序排序",
        );
        View::assign("orderInc",$this->orderInc);
        //角色列表
        $this->roleInc=Db::name("role")->order('id desc')->select();
        View::assign("roleInc",$this->roleInc);
        //会员组列表
        $this->memberGroupInc=Db::name("member_group")->order("group_id asc")->select();
        View::assign("memberGroupInc",$this->memberGroupInc);
        //列表模板
        $where=[];
        $where[]=['type','=','list'];
       $this->listtemp=Db::name("template")->where($where)->order("sort asc,template_id desc")->select();
       View::assign("listtemp",$this->listtemp);
        //列表模板
        $where=[];
        $where[]=['type','=','view'];
       $this->viewtemp=Db::name("template")->where($where)->order("sort asc,template_id desc")->select();
       View::assign("viewtemp",$this->viewtemp);
    }
    public function index(){
        navFun();
        $data=$this->showCat();
        View::assign("data",$data);
        return View::fetch();
    }
    public function index2(){
        $where=array();
        $keywords=Request::param('keywords',"","trim");
        if($keywords){
            $field_name=Request::param('field_name',"","trim");
            if($field_name){
                $where[]=array($field_name,"like","%".$keywords."%");
            }else{
                $where[]=array("name|catid|pid|classpath","like","%".$keywords."%");
            }
        }
        $modelid=Request::param('modelid',0,"intval");
        if($modelid){
            $where[]=["modelid","=",$modelid];
        }
        $listRows=Request::param("listRow")?Request::param("listRow"):config("app.page_show_line");//每页显示多少条
        $total=$this->model->where($where)->count();
        $data=$this->model::where($where)->order("sort asc,catid asc")->paginate(['list_rows'=>$listRows,'query' => request()->param()]);
        // 获取分页显示
        $pagelist = $data->render();

        View::assign("pagelist",$pagelist);
        foreach($data as $key=>$v){
            $data[$key]['catnav']=$this->nav_arr($v['catid']);
            $data[$key]['modelname']=$GLOBALS['model'][$v['modelid']]['name'];
        }
        View::assign("data",$data);
        return View::fetch();
    }
    //设置状态是否启用
    public function setStatus(){
        $catid=Request::param('catid',0,"intval");
        $status=Request::param('status',0,"intval");
        $this->model->update(['catid'=>$catid,'status'=>$status]);
        //记录日志
        $this->UserLogModel->add(Request()->action(),$this->model->getName(),$catid);
        $this->success("设置成功");
    }

    //返回的是一个多维的数组
    public function forCatArray($pid=0){
        $where["pid"]=$pid;
        if($this->modelid){
            $where["modelid"]=$this->modelid;
        }
        $where["status"]=1;
        $cat=Db::name("cat")->field("catid,level,name,modelid,status,sort,pid")->where($where)->order("sort asc,catid asc")->select()->toArray();
        if(count($cat)>0){
            foreach($cat as $key=> $v){
                //验证权限
                if(!check_user_cat("info_view",$v['catid'])){
                    continue;
                }else{
                    $Rcat[$key]=$v;
                    $Rcat[$key]["sub_cat"]=$this->forCatArray($v['catid']);
                }
            }
            return $Rcat;
        }else{
            return $Rcat;
        }
    }
    //返回的是一个数组,显示所有栏目
    public function showCat($pid=0,$str=array()){
        $where[]=["pid","=",$pid];
        $cat=$this->model->field("catid,level,name,modelid,status,sort,pid")->where($where)->order("sort asc,catid asc")->select()->toArray();
        if(count($cat)>0){
            foreach($cat as $v){
                $nbsp_str="";
                for($i=1;$i<$v['level'];$i++){
                    $nbsp_str.="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                }
                if($this->select_catid&&$this->select_catid==$v['catid']){
                    $this_selected="selected";
                }else{
                    $this_selected="";
                }
                $str1=array();
                $str1=$v;
                $str1["str"]=$nbsp_str."|-";
                $str[]=$str1;
                $str=$this->showCat($v['catid'],$str);
            }
            return $str;
        }else{
            return $str;
        }
    }
    //栏目分类
    public function getCat($pid){
        $catstr=$this->forCatOption($pid);
        return $catstr;
    }
    protected function forCatOption($pid=0,$str=""){
        $where[]=["pid","=",$pid];
        $where[]=["status","=",1];
        $cat=$this->model->field("catid,name,level")->where($where)->order("sort asc,catid asc")->select();
        if(count($cat)>0){
            foreach($cat as $v){
                $nbsp_str="";
                for($i=1;$i<$v['level'];$i++){
                    $nbsp_str.="&nbsp;&nbsp;";
                }
                if($this->select_catid&&$this->select_catid==$v['catid']){
                    $this_selected="selected";
                }else{
                    $this_selected="";
                }
                $str.="<option value='{$v['catid']}' ".$this_selected.">{$nbsp_str}|-{$v['name']}</option>";
                $str=$this->forCatOption($v['catid'],$str);
            }
            return $str;
        }else{
            return $str;
        }
    }
    public function add(){
        if(request()->isPost()){
            $data=$this->request->param();
            //如果没有填写路径 默认一个
            if(!$data['classpath']){
                $data['classpath'] = '/'.make_pubid().'/';
            }
            //模型数据
            $ModelModel=$this->ModelModel->find($data["modelid"]);
            //验证
            $this->dataCheck($ModelModel,$data,"add");
            //数据加工处理(返回的包括主表和副表的数据)
            $AllData=$this->dataCreate($ModelModel,$data,"add");
            //保存主表
            $this->model->save($AllData['cat']);
            $lastId=$this->model->catid;
            //保存副表
            $AllData['cat_data']['catid']=$lastId;
            Db::name("cat_data")->insert($AllData['cat_data']);
            //更新权限
            $this->updateRole($lastId);
            $this->UserLogModel->add(Request()->action(),$this->model->getName(),$lastId,$this->request->param());
            $this->RouteModel->updateCatRoute();//更新路由
            //更新缓存
            $this->model->updateCache();
            $this->success("添加成功");
        }else{
            $modelid=Request::param('modelid',0,"intval");
            View::assign("modelid",$modelid);                  
            $parentinfo=[];
            $pid=Request::param('pid',0,"intval");
            if($pid){
                $parentinfo=$this->model->where("catid",$pid)->find();
                $this->select_catid=$pid;
                View::assign("classpath",$parentinfo["classpath"]."newpath".make_pubid()."/");
                View::assign("pid",$pid);
            }
            $copyinfo=[];
            $catid=Request::param('catid',0,"intval");
            if($catid){
                $copyinfo=$this->model->where("catid",$catid)->find();
                View::assign("copyinfo",$copyinfo);
                View::assign("catid",$catid);
            }            
            //栏目对应的模型信息
            $ModelModel=$this->ModelModel->find($modelid);
            $ModelModel["cat_is_enter"]=trim($ModelModel["cat_is_enter"],",");
            View::assign("ModelModel",$ModelModel);
            View::assign("CatFormTemp","../app/data/modelTemp/".$modelid."_cat.php");
            //
            View::assign("pubid", make_pubid());
            View::assign("cat",$this->getCat(0));
            //获取最大的排序          
            $sort=$this->model->where("pid",$pid)->max('sort');
            $sort=$sort+10;
            return View::fetch();
        }
    }
    public function update(){
        if(request()->isPost()){
            $data=$this->request->param();
            //模型数据
            $ModelModel=$this->ModelModel->find($data["modelid"]);
            //验证
            $this->dataCheck($ModelModel,$data,"update");
            //修改前的数据
            $beforData=$this->model->find($data['catid']);
            //父栏目不能是自己的子栏目，否则就是乱伦了
            if(strstr($beforData["son_catids"],"|".$data["pid"]."|")){
                $this->error("父栏目不能是自己的子栏目！");
            }
            //数据加工处理(返回的包括主表和副表的数据)
            $AllData=$this->dataCreate($ModelModel,$data,"update");
            //保存主表
            $this->model->update($AllData['cat']);
            //保存副表
            Db::name("cat_data")->update($AllData['cat_data']);
            //更新权限
            $this->updateRole($data['catid']);
            //
            //更新parent_catids字段，son_catids字段
            $this->model->updateParent_catids($data['catid']);
            $this->model->updateSon_catids($data['catid']);
            //修改后的数据
            $afterData=$this->model->find($data['catid']);
            //把旧的parent_catids字段，son_catids字段和新的parent_catids字段，son_catids字段结果组合在一起，再逐一对每条信息更新父级字段和子级字段
            $arrid_str=$beforData['parent_catids'].$beforData['son_catids'].$afterData['parent_catids'].$afterData['son_catids'];
            $arrid_str_arr=explode("|",$arrid_str);
            $arrid_str_arr = array_unique($arrid_str_arr);
            foreach($arrid_str_arr as $catid_val){
                if($catid_val){
                    $this->model->updateParent_catids($catid_val);
                    $this->model->updateSon_catids($catid_val);
                }
            }
            //需要将son_catids里所有catid对应的信息，重新计算level
            $this->model->updateSon_catidsLevel($afterData['son_catids']);
            //
            $this->UserLogModel->add(Request()->action(),$this->model->getName(),$data['catid'],$this->request->param());
            //更新缓存
            $this->model->updateCache();
            $this->RouteModel->updateCatRoute();//更新路由
            $this->success("修改成功");
        }else{
            $catid=Request::param('catid',0,"intval");
            View::assign("catid",$catid);
            $index_data=Db::name("cat")->find($catid);//主表不要用模型，因为模型返回的是对象，不好用下面的array_merge函数
            $data=Db::name("cat_data")->find($catid);
            $r=array_merge($index_data,$data);
            View::assign("r",$r);
            //栏目对应的模型信息
            $modelid=Request::param('modelid',0,"intval")?Request::param('modelid',0,"intval"):$r["modelid"];
            View::assign("modelid",$modelid);
            $ModelModel=$this->ModelModel->find($modelid);
            $ModelModel["cat_is_enter"]=trim($ModelModel["cat_is_enter"],",");
            View::assign("ModelModel",$ModelModel);
            View::assign("CatFormTemp","../app/data/modelTemp/".$modelid."_cat.php");
            //
            $this->select_catid=$r["pid"];
            View::assign("cat",$this->getCat(0));
            return View::fetch();
        }
    }
    //删除
    public function delete(){
        $catid=Request::param('catid',0,"intval");
        $count=$this->model->where("pid",$catid)->count();
        if($count>0){
            $this->error("该节点下有子栏目，如要删除请先删除子栏目");
        }else{
            //找出父栏目catid
            $r=$this->model->find($catid);
            //删除主表
            $this->model->where("catid",$catid)->delete();
            //删除副表
            Db::name("cat_data")->where("catid",$catid)->delete();
            //写日志
            $this->UserLogModel->add(Request()->action(),$this->model->getName(),$catid,$this->request->param());
            //更新缓存
            $this->model->updateCache();
            $this->RouteModel->updateCatRoute();//更新路由
            $this->success("删除成功");
        }
    }
    //数据校验
    private function dataCheck($ModelModel,$data,$type="add"){
        //录入项
        $cat_is_enter=$ModelModel["cat_is_enter"];
        $is_enter_arr=explode(",",trim($cat_is_enter,","));
        $fieldarr=$this->CatFieldModel->where("field","in",$is_enter_arr)->select();
        foreach($fieldarr as $v){
            //必填项(不能为空验证)
            if(strstr($ModelModel["cat_must_enter"],",".$v['field'].",")){
                //判断是不是checkbox,如果是执行函数验证
                if($v['formtype']=="checkbox"){
                    $this->validate->message[$v['field'].".require"]=$v['name']."必须勾选!";
                    $this->validate->rule[$v['field']][]="require";
                }
                //判断是不是多图上传
                elseif($v['formtype']=="morepic"){
                    $this->validate->message[$v['field']."_smallimg.require"]="请上传".$v['name']."!";
                    $this->validate->rule[$v['field']."_smallimg"][]="require";
                }
                else{
                    $this->validate->message[$v['field'].".require"]="请填写".$v['name']."!";
                    $this->validate->rule[$v['field']][]="require";
                }
            }
            //正则验证
            if($v['pattern']){
                $this->validate->message[$v['field'].".regex"]=$v['errortips']?$v['errortips']:$v['name']."验证不通过!";
                $this->validate->regex[$v['field']."_regex"]=$v['pattern'];
                $this->validate->rule[$v['field']]["regex"]=$v['field']."_regex";
            }
            //值维一验证
            if($v['isunique']){
                $this->validate->message[$v['field'].".unique"]=$v['name']."对应的记录已存在!";
                $tableName=$v['issystem']?"cat":"cat_data";
                if($type=="add"){
                    $this->validate->rule[$v['field']]["unique"]=$tableName;
                }else{
                    //排除自己
                    $this->validate->rule[$v['field']]["unique"]=$tableName.",".$v['field'].",".$data["catid"];
                }
            }
        }
        //
        if(!$this->validate->check($data)){
            $this->error($this->validate->getError());
        }
    }
    private function dataCreate($ModelModel,$data,$type="add"){
        $return=[];
        $return["cat"]=$data;
        //表名
        $return["cat"]["table_name"]=$ModelModel["table_name"];
        //
        if($type=="update"){
            $return["cat"]['catid']=$data['catid'];
            $return["cat_data"]['catid']=$data['catid'];
        }
        //会员组
        if($data['member_group_id']){
           $data['member_group_id']=implode("|",$data['member_group_id']);
           $return["system"]['member_group_id']="|".$data['member_group_id']."|";
        }
        //level
        if($data['pid']){
            $level=$this->model->where("catid",$data['pid'])->value("level");
            $level=$level+1;
            $return["cat"]['pid']=$data['pid'];
            $return["cat"]['level']=$level;
        }else{
            $return["cat"]['pid']=0;
            $return["cat"]['level']=1;
        }
        //录入项
        $cat_is_enter=$ModelModel["cat_is_enter"];
        $is_enter_arr=explode(",",trim($cat_is_enter,","));
        $fieldarr=$this->CatFieldModel->where("field","in",$is_enter_arr)->select();
        foreach($fieldarr as $v){
            //复选框 多选下拉
            if($v['formtype']=="checkbox"||$v['formtype']=="selects"){
                //为数据导入的时候，表格里填写的是:上网|听音乐|打游戏 只要两边增加|即可
                if($type=="import_add"||$type=="import_update"){
                    if($data[$v['field']]){
                        $data[$v['field']]="|".$data[$v['field']]."|";
                    }
                }else{
                    $data[$v['field']]=implode("|",$data[$v['field']]);
                    if($data[$v['field']]){
                        $data[$v['field']]="|".$data[$v['field']]."|";
                    }
                }
            }
            //多图上传
            if($v['formtype']=="morepic"){
                $morepic_str="";
                $smallimg=$data[$v['field']."_smallimg"];
                $bigimg=$data[$v['field']."_bigimg"];
                $imgname=$data[$v['field']."_imgname"];
                foreach($smallimg as $key=>$val){
                    $morepic_str.=$smallimg[$key]."||".$bigimg[$key]."||".$imgname[$key]."\r\n";
                }
                $morepic_str=trim($morepic_str,"\r\n");
                $data[$v['field']]=$morepic_str;
            }
            //多值字段
            if($v['formtype']=="morevalue"){
                $morevalue_str="";
                $fieldLen=$data[$v['field']."_morevalue_len"];//获取一共有多少列字段
                $fieldValArr=array();
                foreach($fieldLen as $k1=>$v1){
                    $fieldValArr[$k1]=$data[$v['field']."_".$k1];
                }
                //根据第一列字段，提取有多个行数据,并循环
                foreach($fieldValArr[0] as $k2=>$v2){
                    //单个信息
                    $row_str="";
                    foreach($fieldValArr as $k3=>$fieldVal){
                        if($k3>0){
                            $row_str.="{{FieldSplit}}".$fieldVal[$k2];
                        }else{
                            $row_str=$fieldVal[$k2];
                        }
                    }
                    //多行信息拼接
                    if($morevalue_str){
                        $morevalue_str.="{{RsSplit}}".$row_str;
                    }else{
                        $morevalue_str=$row_str;
                    }
                }
                $data[$v['field']]=$morevalue_str;
            }
            //日期
            if($v['formtype']=="date"){
               $data[$v['field']]=$data[$v['field']]?strtotime($data[$v['field']]):"";
            }
            //判断是否为 int smallint tinyint bigint
            if(in_array($v['fieldtype'],array("tinyint","smallint","int","bigint"))){
               $data[$v['field']]=abs($data[$v['field']]);//禁止出现负数
            }
            //函数验证(注意：tp6验证不支持函数验证，这里是直接验证的，没有用到tp6的验证方法)
            if($v['savefun']&&strstr($v['savefun_trigger'],"|".$type."|")){
                $savefunArr=explode("###",$v['savefun']);
                $funVal=array();
                if($savefunArr[1]){
                    $funParmas=explode(",",$savefunArr[1]);
                    $funVal=array_merge(array($data[$v['field']]),$funParmas);
                }else{
                    $funVal=array($data[$v['field']]);
                }
                $data[$v['field']]=call_user_func_array($savefunArr[0],$funVal);
            }
           //检测是不是副表字段
             if($v['issystem']){
                $return["cat"][$v['field']]=$data[$v['field']];
            }else{
                unset($return["cat"][$v['field']]);
                $return["cat_data"][$v['field']]=$data[$v['field']];
            }
        }
        return $return;
    }
    //更新权限
    protected function updateRole($catid){
        $role=Db::name("role")->select();
        foreach($role as $v){
            $saveData=array();
            $saveData["id"]=$v['id'];
            if($_POST["view_role_".$v['id']]){
                $saveData["info_view"]=$this->addCatidStr($v["info_view"],$catid);
            }else{
                $saveData["info_view"]=$this->removeCatidStr($v["info_view"],$catid);
            }
            if($_POST["add_role_".$v['id']]){
                $saveData["info_add"]=$this->addCatidStr($v["info_add"],$catid);
            }else{
                $saveData["info_add"]=$this->removeCatidStr($v["info_add"],$catid);
            }
            if($_POST["editor_role_".$v['id']]){
                $saveData["info_editor"]=$this->addCatidStr($v["info_editor"],$catid);
            }else{
                $saveData["info_editor"]=$this->removeCatidStr($v["info_editor"],$catid);
            }
            if($_POST["delete_role_".$v['id']]){
                $saveData["info_delete"]=$this->addCatidStr($v["info_delete"],$catid);
            }else{
                $saveData["info_delete"]=$this->removeCatidStr($v["info_delete"],$catid);
            }
            if($_POST["checked_role_".$v['id']]){
                $saveData["info_checked"]=$this->addCatidStr($v["info_checked"],$catid);
            }else{
                $saveData["info_checked"]=$this->removeCatidStr($v["info_checked"],$catid);
            }
            Db::name("role")->update($saveData);
        }
    }
    //更新权限里用到的函数
    protected function addCatidStr($str,$catid){
        if(strstr($str,"|".$catid."|")){
            return $str;
        }else{
            return $str."|".$catid."|";
        }
    }
    //更新权限里用到的函数
    protected function removeCatidStr($str,$catid){
        return str_replace("|".$catid."|","", $str);
    }
    //返回的是一个不包含首页的栏目结构数组
    public function nav_arr($catid){
        $catarr=array();
        if($GLOBALS['cat'][$catid]){
            $catarr[]=array(
                "catid"=>$catid,
                "name"=>$GLOBALS['cat'][$catid]["name"],
                "modelid"=>$GLOBALS['cat'][$catid]["modelid"],
            );
            for($i=1;$i<=2;$i++){
                $pid=$GLOBALS['cat'][$catid]["pid"];
                if($pid){
                    $catarr[]=array(
                        "catid"=>$pid,
                        "name"=>$GLOBALS['cat'][$pid]["name"],
                        "modelid"=>$GLOBALS['cat'][$pid]["modelid"],
                    );
                    $catid=$pid;
                    $i=1;
                }else{
                    break;
                }
            }
        }
        //数组颠倒
        if($catarr){
            $catarr=array_reverse($catarr);
        }
        foreach($catarr as $v){
            if($navstr){
                $navstr.=' <i class="layui-icon layui-icon-right" style="color:#333; font-size:12px"></i> <a href="'.caturl($v['catid']).'" title="catid:'.$v['catid'].'">['.$v['name'].']</a> ';
            }else{
                $navstr.='<a href="'.caturl($v['catid']).'" title="catid:'.$v['catid'].'">['.$v['name'].']</a>';
            }
        }
        return $navstr;
    }

    //字段排序
    public function updateSort(){
        $catids=Request::param("catids");
        $sort=Request::param("sort");
        foreach($catids as $key=>$catid){
            $data['catid']=(int)$catid;
            $data['sort']=(int)$sort[$key];
            Db::name('cat')->save($data);
        }
        $this->success("排序更改成功");
    }
}
